package com.user.basic.analyze.register;

import com.entity.analyze.Register;
import com.entity.analyze.RegisterType;
import com.user.basic.analyze.BaseAnalyzeService;
import org.springframework.stereotype.Service;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
public abstract class RegisterAnalyzeServiceImpl extends BaseAnalyzeService<RegisterAnalyzeEntity>
        implements RegisterAnalyzeService {

    private final SoftReference<ConcurrentHashMap<String, List<Date>>> cache =
            new SoftReference<>(new ConcurrentHashMap<>());

    private final RegisterAnalyzeMapper registerAnalyzeMapper;

    public RegisterAnalyzeServiceImpl(RegisterAnalyzeMapper registerAnalyzeMapper) {
        this.registerAnalyzeMapper = registerAnalyzeMapper;
    }

    @Override
    public void group() {
        if (Objects.requireNonNull(cache.get()).size() < 1) {
            doGroup();
        }
        save(transform(cache));
    }

    protected abstract void save(Map<Object, Integer> transform);

    protected abstract Map transform(Reference<ConcurrentHashMap<String, List<Date>>> cache);

    private void doGroup() {
        if (Objects.requireNonNull(cache.get()).size() < 1) {
            Date minCreateTime = minCreateTime();
            Calendar now = Calendar.getInstance();
            now.set(now.get(Calendar.YEAR), 11, 31, 23, 59, 59);
            do {
                Calendar calendar = (Calendar) now.clone();
                calendar.add(Calendar.YEAR, -10);
                calendar.set(calendar.get(Calendar.YEAR), 0, 1, 1, 0, 0);
                Date beginDate = calendar.getTime();
                if (beginDate.getTime() < minCreateTime.getTime()) {
                    beginDate = minCreateTime;
                }
                List<Date> dates = registerAnalyzeMapper.selectCreateTime(beginDate, now.getTime());
                 cache.get().put(beginDate.toString().concat("-").concat(now.getTime().toString()), dates);

                now.add(Calendar.YEAR, -10);
            } while (now.get(Calendar.YEAR) > (minCreateTime.getYear() + 1900));
        }
    }

    @Override
    public Date minCreateTime() {
        return registerAnalyzeMapper.minCreateTime();
    }

    @Override
    public void save(List<RegisterAnalyzeEntity> t) {

    }

    static Integer apply(Object t, Integer u) {
        if (null != u) {
            return 1 + u;
        } else {
            return 1;
        }
    }

    protected void save(Map<?, Integer> countMap,RegisterType registerType) {
        if (null != countMap){
            countMap.forEach((k, v) -> {
                Register register = new Register();
                register.setId(UUID.randomUUID().toString());
                register.setName(k.toString());
                register.setTotal(v);
                register.setType(registerType);
                register.setCreateTime(new Date());
                registerAnalyzeMapper.save(register);
            });
        }
    }

    public void save(Register register){
        registerAnalyzeMapper.save(register);
    }
}
